/* * Sun Public License Notice * * The contents of this file are subject to the Sun Public License * Version 1.0 (the "License"). You may not use this file except in * compliance with the License. A copy of the License is available at * http://www.sun.com/ * * The Original Code is Forte for Java, Community Edition. The Initial * Developer of the Original Code is Sun Microsystems, Inc. Portions * Copyright 1997-2000 Sun Microsystems, Inc. All Rights Reserved. */ package org.openide.awt; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.awt.event.MouseMotionListener; import java.util.Enumeration; import java.util.Vector; import javax.swing.*; import org.openide.util.NbBundle; import org.openide.awt.JPopupMenuPlus; /** The SplittedPanel widget is a Panel that can contain one or two components and * place them side-by-side vertically or horizontally with a splitter in the middle. * User can move the split point by dragging the splitter with mouse. * The two components are accessed by add/remove methods with constraints value * ADD_SPLITTER, ADD_FIRST, ADD_SECOND, .... * The split position could be either absolute or proportional (according to the * "Absolute" property setting) - in thwe absolute mode the split point remains same * when resizing (i.e. the left/top component keeps its size and only the * right/bottom component resizes), while in the proportional mode the splitPosition * is a percentage of the width/height assigned to the left/top component. * <P><TABLE BORDER COLS=3 WIDTH=100%> * <TR><TH WIDTH=15%>Property<TH WIDTH=15%>Property Type<TH>Description * <TR><TD> SplitType <TD> int <TD> The type of the splitting - HORIZONTAL, VERTICAL or NONE * <TR><TD> SplitPosition <TD> int <TD> The position of the split point - either absolute position or number of percents * according to the "Absolute" property settings, could be one of FIRST_PREFERRED or * SECOND_PREFERRED, which means that the split point should be placed so that * the first(left/top) resp. second (bottom/rignt) is sized according to its preferredSize * (in this case the Absolute property setting is ignored) * <TR><TD> SplitterType <TD> int <TD> The type of the component that renders the splitter - DEFAULT_SPLITTER, RAISED_SPLITTER, * EMPTY_SPLITTER. * <TR><TD> SplitterComponent <TD> Component <TD> The component that renders the splitter. A custom component can be provided in addition to EMPTY_SPLITTER and RAISED-SPLITTER using this method. * <TR><TD> SplitAbsolute <TD> boolean <TD> if true then the meaning of the SplitPosition is absolute points, * otherwise the SplitPosition is a number of percents * <TR><TD> SplitDragable <TD> boolean <TD> if true then the split point can be dragged using a mouse, * otherwise the SplitPosition is fixed * <TR><TD> SplitTypeChangeEnabled <TD> boolean<TD> if true then the split type can be changed via popup menu commands * <TR><TD> SwapPanesEnabled <TD> boolean<TD> if true then the panes can be swapped via popup menu command * </TABLE> * * @author Ian Formanek */ public class SplittedPanel extends javax.swing.JComponent { /** generated Serialized Version UID */ static final long serialVersionUID = 5058424218525927233L; /** constant for no split - only the first (left/top) component will be shown */ public final static int NONE = 0; /** constant for vertical split */ public final static int VERTICAL = 1; /** constant for horizontal split */ public final static int HORIZONTAL = 2; /** constraints constant for adding a splitter */ public static final Object ADD_SPLITTER = new Integer(0); /** constraints constant for adding a component to the first (left/top) pane */ public static final Object ADD_FIRST = new Integer(1); /** constraints constant for adding a component to the second (right/bottom) pane */ public static final Object ADD_SECOND = new Integer(2); /** constraints constant for adding a component to the left(top) pane (an alias for the ADD_FIRST constant) */ public static final Object ADD_LEFT = ADD_FIRST; /** constraints constant for adding a component to the top(left) pane (an alias for the ADD_FIRST constant) */ public static final Object ADD_TOP = ADD_FIRST; /** constraints constant for adding a component to the right(bottom) pane (an alias for the ADD_SECOND constant) */ public static final Object ADD_RIGHT = ADD_SECOND; /** constraints constant for adding a component to the bottom(right) pane (an alias for the ADD_SECOND constant) */ public static final Object ADD_BOTTOM = ADD_SECOND; /** constant for moving the split point so that the first (left/top) component is sized according to its preferredSize */ public static final int FIRST_PREFERRED = -1; /** constant for moving the split point so that the second (right/bottom) component is sized according to its preferredSize */ public static final int SECOND_PREFERRED = -2; /** constant for splitter component types - raised splitter*/ public static final int RAISED_SPLITTER = 0; /** constant for splitter component types - empty splitter */ public static final int EMPTY_SPLITTER = 1; /** constant for splitter component types - default splitter (raised)*/ public static final int DEFAULT_SPLITTER = RAISED_SPLITTER; /** Constructs a new empty SplittedPanel with no spliting. */ public SplittedPanel () { setLayout (new SplitLayout()); add(splitter, ADD_SPLITTER); init(); } /** Initializes the SplittedPanel */ private void init() { setSplitterCursor(); mouseAdapter = new MouseListenerAdapter(); if (dragable) { splitter.addMouseMotionListener(mouseAdapter); splitter.addMouseListener(mouseAdapter); } popupMenu = new JPopupMenuPlus(); java.util.ResourceBundle awtBundle = NbBundle.getBundle ("org.openide.awt.Bundle"); // NOI18N popupMenu.add(verticalCMI = new JCheckBoxMenuItem(awtBundle.getString("SplittedPanelVertical"))); popupMenu.add(horizontalCMI = new JCheckBoxMenuItem(awtBundle.getString("SplittedPanelHorizontal"))); popupMenu.add(new JSeparator()); popupMenu.add(swapCMI = new JMenuItem(awtBundle.getString("SplittedPanelSwap"))); updatePopupMenu(); ActionListener al = new ActionListener() { public void actionPerformed(ActionEvent e) { if (horizontalCMI.equals(e.getSource())) setSplitType(HORIZONTAL); else setSplitType(VERTICAL); } }; verticalCMI.addActionListener(al); horizontalCMI.addActionListener(al); swapCMI.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { swapPanes(); } } ); } /** Updates splitting, too. */ public void updateUI() { super.updateUI(); updateSplitting(); } /** Updates the visual state and layout when the split state changes. */ protected void updateSplitting() { if (firstComponent != null && secondComponent != null) { invalidate(); firstComponent.invalidate(); splitter.invalidate(); secondComponent.invalidate(); validate(); } } /** Computes component sizes after performing the flip, * it means splitTypeChange */ protected void computeSizesAfterFlip () { if (firstComponent == null || secondComponent == null) return; Dimension ourSize = getSize(); int splitterSize; switch (splitType) { case VERTICAL: if (ourSize.width == 0) break; splitterSize = splitter.getPreferredSize ().height; int newHeight = (ourSize.height - splitterSize) * firstComponent.getSize().width / ourSize.width; firstComponent.setSize(new Dimension(ourSize.width, newHeight)); secondComponent.setSize(new Dimension(ourSize.width, ourSize.height - newHeight - splitterSize)); break; case HORIZONTAL: if (ourSize.height == 0) break; splitterSize = splitter.getPreferredSize ().width; int newWidth = (ourSize.width - splitterSize) * firstComponent.getSize().height / ourSize.height; firstComponent.setSize(new Dimension(newWidth, ourSize.height)); secondComponent.setSize(new Dimension(ourSize.width - newWidth - splitterSize, ourSize.height)); break; } } /** Updates the splitter's cursor according to the current SplittedPanel settings. */ protected void setSplitterCursor() { if (dragable) { if (splitType == VERTICAL) splitter.setCursor(Cursor.getPredefinedCursor(Cursor.N_RESIZE_CURSOR)); else splitter.setCursor(Cursor.getPredefinedCursor(Cursor.W_RESIZE_CURSOR)); } else splitter.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); } /** Updates the splitter's popup menu. */ protected void updatePopupMenu() { if (splitType == VERTICAL) { verticalCMI.setState(true); horizontalCMI.setState(false); } else { verticalCMI.setState(false); horizontalCMI.setState(true); } if (splitTypeChangeEnabled) { verticalCMI.setEnabled(true); horizontalCMI.setEnabled(true); } else { verticalCMI.setEnabled(false); horizontalCMI.setEnabled(false); } if (swapPanesEnabled) swapCMI.setEnabled(true); else swapCMI.setEnabled(false); } /** Swaps the panes.*/ public void swapPanes() { if (!swapPanesEnabled) return; if ((firstComponent == null) || (secondComponent == null)) return; splitIsChanging = true; panesSwapped = !panesSwapped; if (keepSecondSame) { keepSecondSame = false; keepFirstSame = true; } else if (keepFirstSame) { keepSecondSame = true; keepFirstSame = false; } Component aFirstComponent = firstComponent; Component aSecondComponent = secondComponent; remove(aFirstComponent); remove(aSecondComponent); add(aSecondComponent, ADD_FIRST); add(aFirstComponent, ADD_SECOND); updateSplitting(); splitIsChanging = false; } /** @return true if the panes are swapped, false otherwise */ public boolean getPanesSwapped() { return panesSwapped; } /////////////////////////////// // Property accessor methods // /////////////////////////////// /** Getter method for the SplitType property. * @return Current SplitType value. */ public int getSplitType() { return splitType; } /** Setter method for the SplitType property. * @param value New SplitType value. */ public void setSplitType(int value) { if (splitType == value) return; int oldSplitType = splitType; splitType = value; if ((oldSplitType != NONE) && (splitType != NONE)) computeSizesAfterFlip(); setSplitterCursor(); updateSplitting(); updatePopupMenu(); } /** Getter method for the SplitPosition property. * @return Current SplitPosition value. */ public int getSplitPosition() { return splitPosition; } /** Setter method for the SplitPosition property. * @param value New SplitPosition value. */ public void setSplitPosition(int value) { if (splitPosition == value) return; int oldValue = splitPosition; splitPosition = value; splitIsChanging = true; updateSplitting(); fireSplitChange(oldValue, splitPosition); splitIsChanging = false; } /** Getter method for the SplitterType property. * @return Current SplitterType value. * @see #EMPTY_SPLITTER * @see #RAISED_SPLITTER * @see #DEFAULT_SPLITTER */ public int getSplitterType() { return splitterType; } /** Setter method for the SplitterType property. * @param value New SplitterType value. * @see #EMPTY_SPLITTER * @see #RAISED_SPLITTER * @see #DEFAULT_SPLITTER */ public void setSplitterType(int type) { if (splitterType == type) return; splitterType = type; switch (splitterType) { case EMPTY_SPLITTER: splitter = new EmptySplitter(); break; default: case RAISED_SPLITTER: splitter = new DefaultSplitter(3); break; } add(splitter, ADD_SPLITTER); updateSplitting(); } /** Getter method for the SplitterComponent property. * @return Current SplitterComponent value. * @see #getSplitterType */ public Component getSplitterComponent() { return splitter; } /** Setter method for the SplitterComponent property. * @param comp New SplitterComponent value. * @see #setSplitterType */ public void setSplitterComponent(Component comp) { if (splitter == comp) return; if (dragable) { splitter.removeMouseMotionListener(mouseAdapter); splitter.removeMouseListener(mouseAdapter); } remove (splitter); splitter = comp; add(splitter, ADD_SPLITTER); if (dragable) { splitter.addMouseMotionListener(mouseAdapter); splitter.addMouseListener(mouseAdapter); } setSplitterCursor(); updateSplitting(); } /** Getter method for the SplitAbsolute property. * @return Current SplitAbsolute value. */ public boolean isSplitAbsolute() { return absolute; } /** Setter method for the SplitAbsolute property. * @param value New SplitAbsolute value. */ public void setSplitAbsolute(boolean value) { if (absolute == value) return; absolute = value; updateSplitting(); } /** Getter method for the SplitDragable property. * @return Current SplitDragable value. */ public boolean isSplitDragable() { return dragable; } /** Setter method for the Dragable property. * @param value New Dragable value. */ public void setSplitDragable(boolean value) { if (dragable == value) return; dragable = value; if (dragable) { splitter.addMouseMotionListener(mouseAdapter); splitter.addMouseListener(mouseAdapter); } else { splitter.removeMouseMotionListener(mouseAdapter); splitter.removeMouseListener(mouseAdapter); } setSplitterCursor(); } /** Getter method for the ContinuousLayout property. * @return Current ContinuousLayout value. */ public boolean isContinuousLayout() { return continuousLayout; } /** Setter method for the ContinuousLayout property. * @param value New ContinuousLayout value. */ public void setContinuousLayout(boolean value) { continuousLayout = value; } /** Getter method for the KeepFirstSame property. * @return Current KeepFirstSame value. */ public boolean getKeepFirstSame () { return keepFirstSame; } /** Setter method for the KeepFirstSame property. * @param value New KeepFirstSame value. */ public void setKeepFirstSame (boolean value) { keepFirstSame = value; } /** Getter method for the KeepSecondSame property. * @return Current KeepSecondSame value. */ public boolean getKeepSecondSame () { return keepSecondSame; } /** Setter method for the KeepSecondSame property. * @param value New KeepSecondSame value. */ public void setKeepSecondSame (boolean value) { keepSecondSame = value; } /** Getter method for the SplitTypeChangeEnabled property. * @return Current SplitTypeChangeEnabled value. */ public boolean isSplitTypeChangeEnabled() { return splitTypeChangeEnabled; } /** Setter method for the SplitTypeChangeEnabled property. * @param value New SplitTypeChangeEnabled value. */ public void setSplitTypeChangeEnabled(boolean value) { if (splitTypeChangeEnabled == value) return; splitTypeChangeEnabled = value; updatePopupMenu(); } /** Getter method for the SwapPanesEnabled property. * @return Current SwapPanesEnabled value. */ public boolean isSwapPanesEnabled() { return swapPanesEnabled; } /** Setter method for the SwapPanesEnabled property. * @param value New SwapPanesEnabled value. */ public void setSwapPanesEnabled(boolean value) { if (swapPanesEnabled == value) return; swapPanesEnabled = value; updatePopupMenu(); } ///////////////////// // Event Listeners // ///////////////////// /** Adds specified listener to the current set of SplitChangeListeners */ public void addSplitChangeListener(SplitChangeListener l) { if (listeners == null) listeners = new Vector(); listeners.addElement(l); } /** Removes specified listener from the current set of SplitChangeListeners */ public void removeSplitChangeListener(SplitChangeListener l) { if (listeners == null) return; listeners.removeElement(l); } /** Fires the SplitChange event */ protected void fireSplitChange(int oldValue, int newValue) { if (listeners == null) return; Vector l; synchronized (this) { l = (Vector)listeners.clone(); } Enumeration en = l.elements (); SplitChangeEvent evt = new SplitChangeEvent (this, oldValue, newValue); while (en.hasMoreElements ()) { SplitChangeListener scl = (SplitChangeListener) en.nextElement (); scl.splitChanged(evt); } } /////////////////// // Inner Classes // /////////////////// /** A listener interface for tracking split point changes */ public static interface SplitChangeListener { /** Called when a split point changes * @param evt The SplitChangeEvent that describes the change */ public void splitChanged (SplitChangeEvent evt); } /** An event that describes a split point change */ public static class SplitChangeEvent extends java.util.EventObject{ /** generated Serialized Version UID */ static final long serialVersionUID = 6748966611210836878L; private int oldValue, newValue; /** Constructs a new SplitChangeEvent for specified source SplittedPanel and * old and new SplitPositions */ public SplitChangeEvent (SplittedPanel splittedPanel, int oldValue, int newValue) { super(splittedPanel); this.oldValue = oldValue; this.newValue = newValue; } /** @return the old splitterPosition */ public int getOldValue() { return oldValue; } /** @return the new splitterPosition */ public int getNewValue() { return newValue; } } /** The EmptySplitter is an empty splitter component with specified width. * It can be used as the splitter via setSplitterComponent. */ public static class EmptySplitter extends JComponent { /** generated Serialized Version UID */ static final long serialVersionUID = 929648193440460693L; private int width; public EmptySplitter () { this (0); } public EmptySplitter (int width) { this.width = width; } public Dimension getPreferredSize() { return new Dimension (width, width); } } /** The DefaultSplitter class implements a splitting line that is to be used as a default splitter for the SplittedPanel. * It paints a raised 3D-line with given width. */ class DefaultSplitter extends JComponent { private int splitterSize; static final long serialVersionUID =-4223135481223014719L; /** * Constructs a new DefaultSplitter with given width. * @param aWidth the desired width of the splitting line, if the value is lower than 2, the width of 2 is used */ public DefaultSplitter(int aSplitterSize) { splitterSize = aSplitterSize; if (splitterSize < 2) splitterSize = 2; } public Dimension getPreferredSize() { return new Dimension (splitterSize, splitterSize); } public void paint(Graphics g) { Dimension size = getSize(); if (splitType == HORIZONTAL) { int pos = (size.width-splitterSize) / 2; g.setColor(SystemColor.controlLtHighlight); g.drawLine(pos, 0, pos, size.height - 1); g.setColor(SystemColor.control); for (int i = 1; i < splitterSize - 2; i++) g.drawLine(pos+i, 0, pos + i, size.height - 1); g.setColor(SystemColor.controlDkShadow); g.drawLine(pos + splitterSize - 1, 0, pos + splitterSize - 1, size.height - 1); } else if (splitType == VERTICAL) { int pos = (size.height-splitterSize) / 2; g.setColor(SystemColor.controlLtHighlight); g.drawLine(0, pos, size.width - 1, pos); g.setColor(SystemColor.control); for (int i = 1; i < splitterSize-2; i++) g.drawLine(0,pos + i, size.width - 1, pos + i); g.setColor(SystemColor.controlDkShadow); g.drawLine(0, pos + splitterSize - 1, size.width - 1, pos + splitterSize - 1); } } } /** * The MouseListenerAdapter class implements the dragging behaviour of the splitter. */ class MouseListenerAdapter extends java.awt.event.MouseAdapter implements MouseListener, MouseMotionListener { /** A method implemented from the MouseListener interface to handle the splitter dragging */ public void mousePressed(MouseEvent e) { // if (e.isPopupTrigger()) if ((e.getModifiers() & e.BUTTON3_MASK) != 0) popupMenu.show(splitter, e.getX(), e.getY()); else dragging = true; } /** A method implemented from the MouseListener interface to handle the splitter dragging */ public void mouseReleased(MouseEvent e) { if (dragging == true && continuousLayout == false) { dragging = false; if (dragPos == -1) return; if (!absolute) { Dimension d = getSize(); if (splitType == VERTICAL) dragPos = (100 * dragPos)/d.height; else dragPos = (100 * dragPos)/d.width; } setSplitPosition(dragPos); dragPos = -1; } } /** A method implemented from the MouseMotionListener interface to handle the splitter dragging */ public void mouseDragged(MouseEvent e) { if (dragging == true && continuousLayout == true) { Dimension d = getSize(); Point splitterPos = splitter.getLocation(); e.translatePoint(splitterPos.x, splitterPos.y); if (splitType == VERTICAL) { dragPos = e.getY(); if (dragPos > d.height) dragPos = d.height; } else { dragPos = e.getX(); if (dragPos > d.width) dragPos = d.width; } if (dragPos < 0) dragPos = 0; if (continuousLayout) { if (dragPos == -1) return; int newDragPos = dragPos; if (!absolute) { if (splitType == VERTICAL) newDragPos = (100 * dragPos)/d.height; else newDragPos = (100 * dragPos)/d.width; } setSplitPosition(newDragPos); } } } /** A method implemented from the MouseMotionListener interface to handle the splitter dragging */ public void mouseMoved(MouseEvent e) { } } /** * The SplitLayout class implements a LayoutManager for the SplittedPanel. */ class SplitLayout extends Object implements LayoutManager2, java.io.Serializable { static final long serialVersionUID =2034500275182524789L; public void addLayoutComponent (String name, Component comp) { throw new IllegalArgumentException("You must use the add(Component, Object) method for adding"); // NOI18N } public void addLayoutComponent(Component comp, Object constraints) { if (constraints == ADD_SPLITTER) // adding a splitter splitter = comp; else if (constraints == ADD_FIRST) { // adding to the left/top if ((firstComponent != null) && (secondComponent == null)) // if we altready have ... [PENDING] secondComponent = firstComponent; firstComponent = comp; if ((secondComponent != null) && (splitType == NONE)) splitType = DEFAULT_SPLIT_TYPE; } else if (constraints == ADD_SECOND) { if (firstComponent == null) firstComponent = comp; else { secondComponent = comp; if (splitType == NONE) splitType = DEFAULT_SPLIT_TYPE; } } else throw new IllegalArgumentException("You must use one of the SplittedPanel.ADD_XXX constraints Objects"); // NOI18N } public void removeLayoutComponent (Component comp) { if (comp.equals(secondComponent)) secondComponent = null; else if (comp.equals(firstComponent)) { firstComponent = null; if (secondComponent != null) { firstComponent = secondComponent; secondComponent = null; } } } public Dimension preferredLayoutSize (Container parent) { int width = 0; int height = 0; if (firstComponent != null) { Dimension d = firstComponent.getPreferredSize(); width = d.width; height = d.height; } if (secondComponent != null) { Dimension d = secondComponent.getPreferredSize(); if (splitType == VERTICAL) { int splitterSize = splitter.getPreferredSize ().height; if (width < d.width) width = d.width; height += splitterSize + d.height; } else { int splitterSize = splitter.getPreferredSize ().width; if (height < d.height) height = d.height; width += splitterSize + d.width; } } return new Dimension(width, height); } public Dimension minimumLayoutSize (Container parent) { int width = 0; int height = 0; if (firstComponent != null) { Dimension d = firstComponent.getPreferredSize(); width = d.width; height = d.height; } if (secondComponent != null) { Dimension d = secondComponent.getPreferredSize(); if (splitType == VERTICAL) { int splitterSize = splitter.getPreferredSize ().height; if (width < d.width) width = d.width; height += splitterSize + d.height; } else { int splitterSize = splitter.getPreferredSize ().width; if (height < d.height) height = d.height; width += splitterSize + d.width; } } return new Dimension(width, height); } public void layoutContainer (Container parent) { Dimension d = parent.getSize(); int sPosition = splitPosition; // 1. first preferred if (splitPosition == FIRST_PREFERRED) { if (splitType == VERTICAL) sPosition = firstComponent.getPreferredSize().height; else sPosition = firstComponent.getPreferredSize().width; // 2. second preferred } else if (splitPosition == SECOND_PREFERRED) { if (splitType == VERTICAL) { sPosition = d.height - splitter.getPreferredSize ().width - secondComponent.getPreferredSize().height; } else { sPosition = d.width - splitter.getPreferredSize ().height - secondComponent.getPreferredSize().width; } // 3. percent position } else if (!absolute) { int sp = splitPosition; if (sp > 100) sp = 100; if (splitType == VERTICAL) sPosition = (d.height * sp) / 100; else sPosition = (d.width * sp) / 100; } if ((splitType != NONE) && (firstComponent != null) && (secondComponent != null)) { // splitted if (splitType == VERTICAL) { int splitterSize = splitter.getPreferredSize ().height; if (keepSecondSame && !splitIsChanging) { Dimension secondSize = secondComponent.getSize (); if (secondSize.height != 0) sPosition = d.height - secondSize.height - splitterSize; } if (sPosition + splitterSize > d.height) sPosition = d.height - splitterSize; if (sPosition < 0) sPosition = 0; firstComponent.setBounds(new Rectangle(0, 0, d.width, sPosition)); splitter.setBounds(new Rectangle(0, sPosition, d.width, splitterSize)); secondComponent.setBounds(new Rectangle(0, sPosition + splitterSize, d.width, d.height - sPosition - splitterSize)); } else { int splitterSize = splitter.getPreferredSize ().width; if (keepSecondSame && !splitIsChanging) { Dimension secondSize = secondComponent.getSize (); if (secondSize.width != 0) sPosition = d.width - secondSize.width - splitterSize; } if (sPosition + splitterSize > d.width) sPosition = d.width - splitterSize; if (sPosition < 0) sPosition = 0; firstComponent.setBounds(new Rectangle(0, 0, sPosition, d.height)); splitter.setBounds(new Rectangle(sPosition, 0, splitterSize, d.height)); secondComponent.setBounds(new Rectangle(sPosition + splitterSize, 0, d.width - sPosition - splitterSize, d.height)); } } else if (firstComponent != null) { firstComponent.setBounds (new Rectangle(0, 0, d.width-1, d.height -1)); if (splitter != null) splitter.setBounds (0, 0, 0, 0); } } public Dimension maximumLayoutSize(Container target) { return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE); } public float getLayoutAlignmentX(Container target) { return 0; } public float getLayoutAlignmentY(Container target) { return 0; } public void invalidateLayout(Container target) {} } /** Deserializes the component and initializes it. */ private void readObject(java.io.ObjectInputStream ois) throws java.io.IOException, ClassNotFoundException { ois.defaultReadObject(); init(); } /////////////////////// // Private variables // /////////////////////// /** the first (left/top) component */ private Component firstComponent = null; /** the second (right/bottom) component */ private Component secondComponent = null; /** the splitter component */ private Component splitter = new DefaultSplitter(3); /** the splitter component type */ private int splitterType = DEFAULT_SPLITTER; /** the mouse adapter that does the dragging of the splitter*/ private transient MouseListenerAdapter mouseAdapter; /** current split type */ private int splitType = NONE; /** current split position */ private int splitPosition = 50; private boolean absolute = false; private boolean dragable = true; private boolean continuousLayout = true; /** current enabled/disabled state of change of split type */ private boolean splitTypeChangeEnabled = true; /** current enabled/disabled state of change of swapping panes */ private boolean swapPanesEnabled = true; /** current keepSecondSame state - this has bigger priority than keepFirstSame */ private boolean keepSecondSame = false; /** current keepFirstSame state */ private boolean keepFirstSame = false; transient private boolean splitIsChanging = false; private int dragPos = -1; private boolean dragging = false; /** true if the panes were swapped, false otherwise */ private boolean panesSwapped = false; /** The default split type */ private final static int DEFAULT_SPLIT_TYPE = HORIZONTAL; /** The default splitter size */ private final static int DEFAULT_SPLITTER_SIZE = 7; /** popup menu for setting vertical/horizontal splitting */ transient private JPopupMenu popupMenu; /** The popup menu item */ transient private JCheckBoxMenuItem verticalCMI; /** The popup menu item */ transient private JCheckBoxMenuItem horizontalCMI; /** The popup menu item */ transient private JMenuItem swapCMI; /** A Vector of SplitChangeListeners * @associates SplitChangeListener*/ transient private Vector listeners; } /* * Log * 13 Gandalf 1.12 3/11/00 Martin Ryzl menufix [by E.Adams, * I.Formanek] * 12 Gandalf 1.11 1/12/00 Ian Formanek NOI18N * 11 Gandalf 1.10 10/22/99 Ian Formanek NO SEMANTIC CHANGE - Sun * Microsystems Copyright in File Comment * 10 Gandalf 1.9 8/9/99 Ian Formanek Generated Serial Version * UID * 9 Gandalf 1.8 6/8/99 Ian Formanek ---- Package Change To * org.openide ---- * 8 Gandalf 1.7 5/7/99 Ian Formanek Fixed using non-default * splitter components * 7 Gandalf 1.6 5/6/99 Jan Jancura * 6 Gandalf 1.5 4/30/99 Ian Formanek Added splitterComponent * property, EmptySplitter can be used with non-zero width. * 5 Gandalf 1.4 3/9/99 Jaroslav Tulach Node actions releases * sometimes its listeners. * 4 Gandalf 1.3 3/8/99 Jaroslav Tulach Bundles. * 3 Gandalf 1.2 3/8/99 Ian Formanek Removed unused imports * 2 Gandalf 1.1 1/6/99 Ian Formanek Reflecting changes in * location of package "awt" * 1 Gandalf 1.0 1/5/99 Ian Formanek * $ * Beta Change History: * 0 Tuborg 0.21 --/--/98 Jan Formanek repaired the "catch the focus" bug * 0 Tuborg 0.25 --/--/98 Jan Formanek SplitLayout made serializable * 0 Tuborg 0.26 --/--/98 Jan Formanek mouseAdapter made transient, readObject implemented appropriately * 0 Tuborg 0.30 --/--/98 Jan Formanek renamed properties Absolute, Dragable to SplitAbsolute, SplitDragable * 0 Tuborg 0.31 --/--/98 Jan Formanek small layout fix * 0 Tuborg 0.32 --/--/98 Jan Formanek getPanesSwapped method added * 0 Tuborg 0.33 --/--/98 Jan Formanek SplitChangeListeners added * 0 Tuborg 0.33 --/--/98 Jan Formanek moving splitter outside visible area bug fixed (BUG #04100005) */